#include <stdio.h>
#include <malloc.h>
#include <stdlib.h>
#include <stdarg.h>
#include <string.h>
#define MAX_ARRAY_DIM 8
#define ERROR 0
#define OK 1
#define OVERFLOW -2
#define UNDERFLOW -3
typedef int ElemType;
typedef int Status;
typedef struct {
    int dim;
    ElemType* base;
    int* bound;
    int* constant;
}Array;
Status InitArray(Array& A, int dim, ...) {
    if (dim < 1 || dim > MAX_ARRAY_DIM)
        return ERROR;
    A.dim = dim;
    A.bound = (int*)malloc(sizeof(int) * dim);
    if (!A.bound)
        exit(OVERFLOW);
    int elemTotal = 1;
    va_list ap;
    va_start(ap, dim);
    for (int i = 0; i < dim; ++i) {
        A.bound[i] = va_arg(ap, int);
        if (A.bound[i] <= 0)
            return ERROR;
        elemTotal *= A.bound[i];
    }
    va_end(ap);
    A.base = (ElemType*)malloc(sizeof(ElemType) * elemTotal);
    memset(A.base, 0, sizeof(ElemType) * elemTotal);
    if (!A.base)
        exit(OVERFLOW);
    A.constant = (int*)malloc(sizeof(ElemType) * dim);
    if (!A.constant)
        exit(OVERFLOW);
    A.constant[dim-1] = 1;
    for (int i = dim - 2; i >= 0; --i) 
        A.constant[i] = A.constant[i+1] * A.bound[i+1];
    return OK;
}
Status Destroy(Array& A) {
    if (!A.base)
        return ERROR;
    free(A.base);
    A.base = nullptr;
    if (!A.bound)
        return ERROR;
    free(A.bound);
    A.bound = nullptr;
    if (!A.constant)
        return ERROR;
    free(A.constant);
    A.constant = nullptr;
    return OK;
}
Status Locate(Array A, va_list ap, int& off) {
    off = 0;
    for (int i = 0; i < A.dim; ++i) {
        int ind = va_arg(ap, int);
        if (ind < 0 || ind >= A.bound[i])
            return ERROR;
        off += ind * A.constant[i];
    }
    return OK;
}
Status Value(Array A, ElemType& e, ...) {
    va_list ap;
    va_start(ap, e);
    int offset;
    int status = Locate(A, ap, offset);
    if (status <= 0)
        return status;
    e = *(A.base + offset);
    va_end(ap);
    return OK;
}
Status Assign(Array& A, ElemType e, ...) {
    va_list ap;
    va_start(ap, e);
    int offset;
    int status = Locate(A, ap, offset);
    if (status <= 0)
        return ERROR;
    *(A.base + offset) = e;
    va_end(ap);
    return OK;
}
int main(void) {
    Array A;
    InitArray(A, 4, 3, 4, 5, 6);
    ElemType e = 5;
    // Assign(A, e, 1, 1, 1, 1);
    // printf("%d\n", e);
    Value(A, e, 1, 1, 1, 1);
    printf("%d\n", e);

    return 0;
}
